/******************************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Ltd.                       */
/*                                                                            */
/*  NAME      = frtds_convert.c                                                 */
/*  NOTE      = 数据类型转换                                                  */
/*  DATE      = 2014/05/29 by zhengxd                                         */
/******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <math.h>

#include "frmem.h"
#include "frstr.h"
#include "frcomm.h"
#include "frlist.h"
#include "frlog.h"
#include "iconv2utf8.h"
#include "frsutl.h"
#include "frhex_dump.h"
#include "frbyte_buffer.h"
#include "module.h"
#include "frtds_convert.h"

#define FRTDS_2_POWER_23  8388608
#define FRTDS_2_POWER_24  16777216
#define FRTDS_2_POWER_52  4503599627370496
#define FRTDS_2_POWER_55  36028797018963968
#define FRTDS_2_POWER_56  72057594037927936

#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
/* 判断是否是闰年 */
#define ISLEAP(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
/* 一年月份分布 */
FR_STATIC const unsigned short int frtds_mon_yday[2][13] =
{
    /* Normal years.  */
    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
    /* Leap years.  */
    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};

/*******************************************************************************
*  FUNC     :  binary转单精度浮点型
*  ARGS     :  p_buffer(入力数据)
*           :  i_float_type(浮点数据类型)
*           :  pp_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_binary_str长度必须是4
*******************************************************************************/
FR_STATIC int __frtds_binary_to_float(char *p_buff
                                   , int i_float_type
                                   , char **pp_value)
{
    float f_sign_bit = 0;
    float f_exponent = 0;
    float f_fraction = 0;
    float f_power = 0;
    float f_value = 0;
    uint32_t u32_byte1 = 0;
    uint32_t u32_byte2 = 0;
    uint32_t u32_byte3 = 0;
    uint32_t u32_byte4 = 0;
    char *p_value = NULL;

    switch (i_float_type)
    {
        case FRTDS_FLT_IEEE_HI:
            u32_byte1 = p_buff[3];
            u32_byte2 = p_buff[2];
            u32_byte3 = p_buff[1];
            u32_byte4 = p_buff[0];
            /* 取得符号位 */
            f_sign_bit = (u32_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            f_exponent = ((u32_byte1 & 0x7F) << 1) + ((u32_byte2 & 0x80) >> 7);
            f_power = powf(2, f_exponent - 127);
            /* 取得尾数 */
            f_fraction = ((u32_byte2 & 0x7F) << 16) + (u32_byte3 << 8) + u32_byte4;
            f_fraction /= FRTDS_2_POWER_23;
            f_fraction += 1.0;
            break;

        case FRTDS_FLT_VAXD:
            u32_byte1 = p_buff[2];
            u32_byte2 = p_buff[3];
            u32_byte3 = p_buff[0];
            u32_byte4 = p_buff[1];
            /* 取得符号位 */
            f_sign_bit = (u32_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            f_exponent = ((u32_byte1 & 0x7F) << 1) + ((u32_byte2 & 0x80) >> 7);
            f_power = powf(2, f_exponent - 127);
            /* 取得尾数 */
            f_fraction = ((u32_byte2 & 0x7F) << 16) + (u32_byte3 << 8) + u32_byte4;
            f_fraction /= FRTDS_2_POWER_24;
            f_fraction += 0.5;
            break;

        case FRTDS_FLT_IEEE_LO:
            u32_byte1 = p_buff[0];
            u32_byte2 = p_buff[1];
            u32_byte3 = p_buff[2];
            u32_byte4 = p_buff[3];
            /* 取得符号位 */
            f_sign_bit = (u32_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            f_exponent = ((u32_byte1 & 0x7F) << 1) + ((u32_byte2 & 0x80) >> 7);
            f_power = powf(2, f_exponent - 127);
            /* 取得尾数 */
            f_fraction = ((u32_byte2 & 0x7F) << 16) + (u32_byte3 << 8) + u32_byte4;
            f_fraction /= FRTDS_2_POWER_23;
            f_fraction += 1.0;
            break;

        case FRTDS_FLT_ND5000:
            u32_byte1 = p_buff[0];
            u32_byte2 = p_buff[1];
            u32_byte3 = p_buff[2];
            u32_byte4 = p_buff[3];
            /* 取得符号位 */
            f_sign_bit = (u32_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            f_exponent = u32_byte1 & 0x7F;
            f_power = powf(16, f_exponent - 64);
            /* 取得尾数 */
            f_fraction = (u32_byte2 << 16) + (u32_byte3 << 8) + u32_byte4;
            f_fraction /= FRTDS_2_POWER_24;
            break;

        default:
            return APM_L7_ANALYZE_FAIL;
    }

    f_value = powf(-1, f_sign_bit) * f_power * f_fraction;
    /* 申请足够长的内存 */
    p_value = (char *)frmalloc(128);
    if (p_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    snprintf(p_value, 128, "%f", f_value);
    *pp_value = p_value;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  binary转双精度浮点型
*  ARGS     :  p_buffer(入力数据)
*           :  i_float_type(浮点数据类型)
*           :  pp_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_binary_str长度必须是8
*******************************************************************************/
FR_STATIC int __frtds_binary_to_double(char *p_buff
                                   , int i_float_type
                                   , char **pp_value)
{
    double d_sign_bit = 0;
    double d_exponent = 0;
    double d_fraction = 0;
    double d_power = 0;
    double d_value = 0;
    uint64_t u64_byte1 = 0;
    uint64_t u64_byte2 = 0;
    uint64_t u64_byte3 = 0;
    uint64_t u64_byte4 = 0;
    uint64_t u64_byte5 = 0;
    uint64_t u64_byte6 = 0;
    uint64_t u64_byte7 = 0;
    uint64_t u64_byte8 = 0;
    char *p_value = NULL;

    switch (i_float_type)
    {
        case FRTDS_FLT_IEEE_HI:
            u64_byte1 = p_buff[7];
            u64_byte2 = p_buff[6];
            u64_byte3 = p_buff[5];
            u64_byte4 = p_buff[4];
            u64_byte5 = p_buff[3];
            u64_byte6 = p_buff[2];
            u64_byte7 = p_buff[1];
            u64_byte8 = p_buff[0];
            /* 取得符号位 */
            d_sign_bit = (u64_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            d_exponent = ((u64_byte1 & 0x7F) << 4) + ((u64_byte2 & 0xF0) >> 4);
            d_power = pow(2, d_exponent - 1023);
            /* 取得尾数 */
            d_fraction = ((u64_byte2 & 0x0F) << 48)
                         + (u64_byte3 << 40)
                         + (u64_byte4 << 32)
                         + (u64_byte5 << 24)
                         + (u64_byte6 << 16)
                         + (u64_byte7 << 8)
                         + u64_byte8;
            d_fraction /= FRTDS_2_POWER_52;
            d_fraction += 1.0;
            break;

        case FRTDS_FLT_VAXD:
            u64_byte1 = p_buff[2];
            u64_byte2 = p_buff[3];
            u64_byte3 = p_buff[0];
            u64_byte4 = p_buff[1];
            u64_byte5 = p_buff[6];
            u64_byte6 = p_buff[7];
            u64_byte7 = p_buff[4];
            u64_byte8 = p_buff[5];
            /* 取得符号位 */
            d_sign_bit = (u64_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            d_exponent = ((u64_byte1 & 0x7F) << 1) + ((u64_byte2 & 0x80) >> 7);
            d_power = pow(2, d_exponent - 127);
            /* 取得尾数 */
            d_fraction = ((u64_byte2 & 0x7F) << 48)
                         + (u64_byte3 << 40)
                         + (u64_byte4 << 32)
                         + (u64_byte5 << 24)
                         + (u64_byte6 << 16)
                         + (u64_byte7 << 8)
                         + u64_byte8;
            d_fraction /= FRTDS_2_POWER_55;
            d_fraction += 0.5;
            break;

        case FRTDS_FLT_IEEE_LO:
            u64_byte1 = p_buff[0];
            u64_byte2 = p_buff[1];
            u64_byte3 = p_buff[2];
            u64_byte4 = p_buff[3];
            u64_byte5 = p_buff[4];
            u64_byte6 = p_buff[5];
            u64_byte7 = p_buff[6];
            u64_byte8 = p_buff[7];
            /* 取得符号位 */
            d_sign_bit = (u64_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            d_exponent = ((u64_byte1 & 0x7F) << 4) + ((u64_byte2 & 0xF0) >> 4);
            d_power = pow(2, d_exponent - 1023);
            /* 取得尾数 */
            d_fraction = ((u64_byte2 & 0x0F) << 48)
                         + (u64_byte3 << 40)
                         + (u64_byte4 << 32)
                         + (u64_byte5 << 24)
                         + (u64_byte6 << 16)
                         + (u64_byte7 << 8)
                         + u64_byte8;
            d_fraction /= FRTDS_2_POWER_52;
            d_fraction += 1.0;
            break;

        case FRTDS_FLT_ND5000:
            u64_byte1 = p_buff[0];
            u64_byte2 = p_buff[1];
            u64_byte3 = p_buff[2];
            u64_byte4 = p_buff[3];
            u64_byte5 = p_buff[4];
            u64_byte6 = p_buff[5];
            u64_byte7 = p_buff[6];
            u64_byte8 = p_buff[7];
            /* 取得符号位 */
            d_sign_bit = (u64_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            d_exponent = u64_byte1 & 0x7F;
            d_power = pow(16, d_exponent - 64);
            /* 取得尾数 */
            d_fraction = (u64_byte2 << 48)
                        + (u64_byte3 << 40)
                        + (u64_byte4 << 32)
                        + (u64_byte5 << 24)
                        + (u64_byte6 << 16)
                        + (u64_byte7 << 8)
                        + u64_byte8;
            d_fraction /= FRTDS_2_POWER_56;
            break;

        default:
            return APM_L7_ANALYZE_FAIL;
    }

    d_value = pow(-1, d_sign_bit) * d_power * d_fraction;
    /* 申请足够长的内存 */
    p_value = (char *)frmalloc(128);
    if (p_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    snprintf(p_value, 128, "%f", d_value);
    *pp_value = p_value;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  将天数转换为年月日
*  ARGS     :  i_days(天数)
*           :  p_ui_year(年)
*           :  p_ui_month(月)
*           :  p_ui_day(日)
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
FR_STATIC void __frtds_days_fromat(int i_days
                               , unsigned int *p_ui_year
                               , unsigned int *p_ui_month
                               , unsigned int *p_ui_day)
{
    unsigned int ui_year_guess = 0;
    unsigned int ui_year = 1900;
    //unsigned int ui_month = 0;
    //unsigned int ui_day = 0;
    unsigned int ui_loop = 0;
    const unsigned short int *p_us_mon_yday;

    while (i_days < 0 || i_days >= (ISLEAP(ui_year) ? 366 : 365))
    {
        /* Guess a corrected year, assuming 365 days per year.  */
        ui_year_guess = ui_year + i_days / 365 - (i_days % 365 < 0);

        /* Adjust DAYS and Y to match the guessed year.  */
        i_days -= ((ui_year_guess - ui_year) * 365
                    + LEAPS_THRU_END_OF(ui_year_guess - 1)
                    - LEAPS_THRU_END_OF(ui_year - 1));
        ui_year = ui_year_guess;
    }

    p_us_mon_yday = frtds_mon_yday[ISLEAP(ui_year)];
    for (ui_loop = 11; i_days < (long int)p_us_mon_yday[ui_loop]; --ui_loop)
    {
        continue;
    }

    *p_ui_day = i_days - p_us_mon_yday[ui_loop] + 1;
    *p_ui_month = ui_loop + 1;
    *p_ui_year = ui_year;
    return;
}

void frtds_free_param(Frdata_field **pp_st_value)
{
    if (pp_st_value == NULL || *pp_st_value == NULL)
    {
        return;
    }
    Frdata_field *p_st_value = *pp_st_value;

    if (p_st_value->p_field_value)
    {
        frfree(p_st_value->p_field_value);
    }
    if (p_st_value->p_field_name)
    {
        frfree(p_st_value->p_field_name);
    }
    frfree(p_st_value);
    *pp_st_value = NULL;
    return;
}

int frtds_create_param(char *p_value
                     , int i_date_type
                     , Frdata_field **pp_st_value)
{
    Frdata_field *p_st_value = NULL;

    /* 申请出力结构体内存 */
    p_st_value = (Frdata_field *)frmalloc(sizeof(Frdata_field));
    if (p_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 设置出力 */
    memset(p_st_value, 0x0, sizeof(Frdata_field));
    p_st_value->em_data_type = (Frdata_type)i_date_type;
    p_st_value->p_field_value = p_value;
    *pp_st_value = p_st_value;
    return APM_L7_ANALYZE_SUCC;
}

int frtds_convert_to_int(Frbyte_Packet *p_st_data
                       , int i_whole_flg
                       , LITTLE_BIG_ENDIAN i_endian
                       , unsigned int ui_int_len
                       , int i_unsigned_flg
                       , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = 0;
    uint8_t u8_int_value = 0;
    char c_int_value = 0;
    uint16_t u16_int_value = 0;
    short s_int_value = 0;
    uint32_t u32_int_value = 0;
    int i_int_value = 0;
    uint64_t u64_int_value = 0;
    long long ll_int_value = 0;
    int i_data_type = 0;
    char *p_int_value = NULL;

    /* 数据长度不足 */
    if (ui_int_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    /* 32位足够存下整形数据 */
    p_int_value = (char *)frmalloc(32);
    if (p_int_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    memset(p_int_value, 0x0, 32);

    /* 根据数值所占据的长度来解析数据 */
    switch (ui_int_len)
    {
        case 1: /* BYTE型 */
            //i_data_type = FRCHAR;
            bytebuff_get_char(p_st_data, &u8_int_value);
            /* 无符号char */
            if (i_unsigned_flg == FR_YES)
            {
                snprintf(p_int_value, 32, "%u", u8_int_value);
            }
            else
            {
                c_int_value = (char)u8_int_value;
                snprintf(p_int_value, 32, "%d", c_int_value);
            }
            break;

        case 2: /* SHORT型 */
            //i_data_type = FRSHORT;
            i_ret = bytebuff_get_short(p_st_data, 2, &u16_int_value, i_endian);
            if (i_ret != FR_SUCC)
            {
                frfree(p_int_value);
                return APM_L7_ANALYZE_FAIL;
            }
            /* 无符号short */
            if (i_unsigned_flg == FR_YES)
            {
                snprintf(p_int_value, 32, "%u", u16_int_value);
            }
            else
            {
                s_int_value = (short)u16_int_value;
                snprintf(p_int_value, 32, "%d", s_int_value);
            }
            break;

        case 4: /* INT型 */
            i_data_type = FRINT;
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_int_value, i_endian);
            if (i_ret != FR_SUCC)
            {
                frfree(p_int_value);
                return APM_L7_ANALYZE_FAIL;
            }
            /* 无符号int */
            if (i_unsigned_flg == FR_YES)
            {
                snprintf(p_int_value, 32, "%u", u32_int_value);
            }
            else
            {
                i_int_value = (int)u32_int_value;
                snprintf(p_int_value, 32, "%d", i_int_value);
            }
            break;

        case 8: /* LONG型 */
            i_data_type = FRLONG;
            i_ret = bytebuff_get_long(p_st_data, 8, &u64_int_value, i_endian);
            if (i_ret != FR_SUCC)
            {
                frfree(p_int_value);
                return APM_L7_ANALYZE_FAIL;
            }
            /* 无符号long */
            if (i_unsigned_flg == FR_YES)
            {
                snprintf(p_int_value, 32, PRI64U, u64_int_value);
            }
            else
            {
                ll_int_value = (long long)u64_int_value;
                snprintf(p_int_value, 32, "%lld", ll_int_value);
            }
            break;

        default:
            frfree(p_int_value);
            return APM_L7_ANALYZE_FAIL;
    }

    /* 做成Frdata_field */
    i_ret = frtds_create_param(p_int_value, i_data_type, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_int_value);
        return APM_L7_ANALYZE_FAIL;
    }
    return APM_L7_ANALYZE_SUCC;
}

int frtds_convert_to_intn(Frbyte_Packet *p_st_data
                        , int i_whole_flg
                        , LITTLE_BIG_ENDIAN i_endian
                        , int i_unsigned_flg
                        , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_len = 0;

    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 1)
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    bytebuff_get_char(p_st_data, &u8_len);
    /* 解析整形 */
    if (u8_len)
    {
        i_ret = frtds_convert_to_int(p_st_data, i_whole_flg, i_endian
                                   , u8_len, i_unsigned_flg, pp_st_value);
    }
    else
    {
        i_ret = frtds_create_param(NULL, FRINT, pp_st_value);
    }
    return i_ret;
}

int frtds_convert_to_boolean(Frbyte_Packet *p_st_data
                            , int i_whole_flg
                            , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = FR_SUCC;
    uint8_t u8_value = 0;
    char *p_boolean = NULL;
    //Frdata_field *p_st_value = NULL;

    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 1)
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    /* 取得boolean值 */
    bytebuff_get_char(p_st_data, &u8_value);
    switch (u8_value)
    {
        case 0x00:
            p_boolean = frstrdup("0");
            if (p_boolean == NULL)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            break;

        case 0x01:
            p_boolean = frstrdup("1");
            if (p_boolean == NULL)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            break;

        default:
            return APM_L7_ANALYZE_FAIL;
    }

    /* 做成Frdata_field */
    i_ret = frtds_create_param(p_boolean, FRBOOLEAN, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_boolean);
        return APM_L7_ANALYZE_FAIL;
    }

    return APM_L7_ANALYZE_SUCC;
}

int frtds_convert_to_booleann(Frbyte_Packet *p_st_data
                             , int i_whole_flg
                             , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_len = 0;

    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 1)
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    bytebuff_get_char(p_st_data, &u8_len);
    /* 解析boolean */
    if (u8_len == 1)
    {
        i_ret = frtds_convert_to_boolean(p_st_data, i_whole_flg, pp_st_value);
    }
    /* NULL */
    else if (u8_len == 0)
    {
        i_ret = frtds_create_param(NULL, FRBOOLEAN, pp_st_value);
    }
    else
    {
        return APM_L7_ANALYZE_FAIL;
    }

    return i_ret;
}

int frtds_convert_to_datetime(Frbyte_Packet *p_st_data
                            , unsigned int ui_datetime_len
                            , LITTLE_BIG_ENDIAN i_endian
                            , int i_whole_flg
                            , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = FR_SUCC;
    uint16_t u16_days = 0;
    uint16_t u16_times = 0;
    uint32_t u32_days = 0;
    uint32_t u32_times = 0;
    int i_days = 0;
    //unsigned int ui_minutes = 0;
    unsigned int ui_year = 1970;
    unsigned int ui_month = 1;
    unsigned int ui_day = 1;
    unsigned int ui_hour = 0;
    unsigned int ui_minute = 0;
    unsigned int ui_second = 0;
    unsigned int ui_msecond = 0;
    char *p_datetime = NULL;
    //Frdata_field *p_st_value = NULL;

    /* 数据长度不足 */
    if (ui_datetime_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    /* 解析datetime */
    if (ui_datetime_len == 4)
    {
        /*
        *  First one 2-byte unsigned integer that represents the number of days
        *  since January 1, 1900. Second one 2-byte unsigned integer that
        *  represents the number of minutes elapsed since 12 A.M. that day.
        */
        i_ret = bytebuff_get_short(p_st_data, 2, &u16_days, i_endian);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        i_ret = bytebuff_get_short(p_st_data, 2, &u16_times, i_endian);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }

        /* 设置取得的时间 */
        i_days = u16_days;
        /* 将天数转换为年月日 */
        __frtds_days_fromat(i_days, &ui_year, &ui_month, &ui_day);
        ui_hour = u16_times / 60;
        ui_minute = u16_times % 60;
        /* 日期格式YYYY-MM-DD HH:mm */
        p_datetime = (char *)frmalloc(17 + 1);
        if (p_datetime == NULL)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        snprintf(p_datetime, 18, "%04d-%02d-%02dT%02d:%02dZ"
                ,ui_year, ui_month, ui_day, ui_hour, ui_minute);
    }
    else if (ui_datetime_len == 8)
    {
        /*
        *  First one 4-byte signed integer that represents the number of days
        *  since January 1, 1900. Negative numbers are allowed to represent
        *  dates since January 1, 1753. Second one 4-byte unsigned integer that
        *  represents the number of one three-hundredths of a
        *  second (300 counts per second) elapsed since 12 A.M. that day.
        */
        i_ret = bytebuff_get_int(p_st_data, 4, &u32_days, i_endian);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        i_ret = bytebuff_get_int(p_st_data, 4, &u32_times, i_endian);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }

        /* 设置取得的时间 */
        if (u32_days != 0xFFFFFFFF) /* 根据java反编译 */
        {
            i_days = u32_days;
            /* 将天数转换为年月日 */
            __frtds_days_fromat(i_days, &ui_year, &ui_month, &ui_day);
        }

        if (u32_times != 0xFFFFFFFF) /* 根据java反编译 */
        {
            ui_hour = u32_times / 1080000;
            u32_times -= ui_hour * 1080000;
            ui_minute = u32_times / 18000;
            u32_times -= ui_minute * 18000;
            ui_second = u32_times / 300;
            u32_times -= ui_second * 300;
            ui_msecond = u32_times * 1000 / 300;
        }

        /* 日期格式yyyy-MM-dd HH:mm:ss.xxx */
        p_datetime = (char *)frmalloc(24 + 1);
        if (p_datetime == NULL)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        snprintf(p_datetime, 25, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ"
                 ,ui_year, ui_month, ui_day, ui_hour
                 , ui_minute, ui_second, ui_msecond);
    }
    else
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 创建参数节点 */
    i_ret = frtds_create_param(p_datetime, FRTIME, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_datetime);
        return APM_L7_ANALYZE_FAIL;
    }
    return APM_L7_ANALYZE_SUCC;
}

int frtds_convert_to_datetimen(Frbyte_Packet *p_st_data
                             , LITTLE_BIG_ENDIAN i_endian
                             , int i_whole_flg
                             , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_len = 0;

    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 1)
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    bytebuff_get_char(p_st_data, &u8_len);
    /* 解析datetime */
    if (u8_len)
    {
        i_ret = frtds_convert_to_datetime(p_st_data, u8_len, i_endian
                                        , i_whole_flg, pp_st_value);
    }
    /* NULL */
    else
    {
        i_ret = frtds_create_param(NULL, FRTIME, pp_st_value);
    }

    return i_ret;
}

int frtds_convert_to_date(Frbyte_Packet *p_st_data
                         , unsigned int ui_date_len
                         , LITTLE_BIG_ENDIAN i_endian
                         , int i_db_type
                         , int i_whole_flg
                         , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = FR_SUCC;
    unsigned int ui_loop = 0;
    unsigned int ui_year = 1970;
    unsigned int ui_month = 1;
    unsigned int ui_day = 1;
    uint32_t u32_days = 0;
    int i_days = 0;
    char *p_date = NULL;
    char arr_buff[4];

    /* 数据长度不足 */
    if (ui_date_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    /*
    *  For MSSQL DATENTYPE, the only valid lengths are 0x03 for
    *  non-NULL instances and 0x00 for NULL instances.
    */
    if (i_db_type == FRTDS_MSSQL)
    {
        /*
        *  IN MSSQL: date is represented as one 3-byte unsigned integer that
        *  represents the number of days since January 1, year 1.
        */
        if (ui_date_len == 3)
        {
            /* 取得天数 */
            i_ret = bytebuff_get_bytes(p_st_data, arr_buff, ui_date_len);
            if (i_ret != FR_SUCC)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            if (i_endian == BYTE_LITTLE_ENDIAN)
            {
                while (ui_date_len--)
                {
                    i_days = (i_days << 8) | (unsigned char)arr_buff[ui_date_len];
                }
            }
            else
            {
                while (ui_loop < ui_date_len)
                {
                    i_days = (i_days << 8) | (unsigned char)arr_buff[ui_loop++];
                }
            }

            /* 将天数转换为年月日 */
            __frtds_days_fromat(i_days, &ui_year, &ui_month, &ui_day);
            /* 日期格式YYYY-MM-DD*/
            p_date = (char *) frmalloc(10 + 1);
            if (p_date == NULL)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            snprintf(p_date, 11, "%04d-%02d-%02d",ui_year, ui_month, ui_day);
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }
    /*
    *  For SYBASE DATENTYPE, the only valid lengths are 0x04 for
    *  non-NULL instances and 0x00 for NULL instances.
    */
    else if (i_db_type == FRTDS_SYBASE)
    {
        if (ui_date_len == 4)
        {
            /*
            *  IN SYBASE: date is represented as one 4-byte signed integer that
            *  represents the number of days since January 1, year 1.
            */
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_days, i_endian);
            if (i_ret != FR_SUCC)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            /* 设置取得的时间 */
            if (u32_days != 0xFFFFFFFF) /* 根据java反编译 */
            {
                i_days = u32_days;
                /* 将天数转换为年月日 */
                __frtds_days_fromat(i_days, &ui_year, &ui_month, &ui_day);
            }
            /* 日期格式YYYY-MM-DD*/
            p_date = (char *) frmalloc(10 + 1);
            if (p_date == NULL)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            snprintf(p_date, 11, "%04d-%02d-%02d",ui_year, ui_month, ui_day);
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 创建参数节点 */
    i_ret = frtds_create_param(p_date, FRTIME, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_date);
        return APM_L7_ANALYZE_FAIL;
    }
    return APM_L7_ANALYZE_SUCC;
}

int frtds_convert_to_daten(Frbyte_Packet *p_st_data
                          , LITTLE_BIG_ENDIAN i_endian
                          , int i_db_type
                          , int i_whole_flg
                          , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_len = 0;

    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 1)
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    bytebuff_get_char(p_st_data, &u8_len);
    /* 解析date */
    if (u8_len)
    {
        i_ret = frtds_convert_to_date(p_st_data, u8_len, i_endian
                                    , i_db_type, i_whole_flg, pp_st_value);
    }
    else
    {
        i_ret = frtds_create_param(NULL, FRTIME, pp_st_value);
    }
    return i_ret;
}

int frtds_convert_to_time(Frbyte_Packet *p_st_data
                         , unsigned int ui_time_len
                         , LITTLE_BIG_ENDIAN i_endian
                         , int i_whole_flg
                         , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = FR_SUCC;
    unsigned int ui_hour = 0;
    unsigned int ui_minute = 0;
    unsigned int ui_second = 0;
    unsigned int ui_msecond = 0;
    uint32_t u32_times = 0;
    char *p_time = NULL;

    /* 数据长度不足 */
    if (ui_time_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    if (ui_time_len == 4)
    {
        /*
        *  one 4-byte unsigned integer that represents the number of one
        *  three-hundredths of a second (300 counts per second)
        *  elapsed since 12 A.M. that day.
        */
        i_ret = bytebuff_get_int(p_st_data, 4, &u32_times, i_endian);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }

        if (u32_times != 0xFFFFFFFF) /* 根据java反编译 */
        {
            ui_hour = u32_times / 1080000;
            u32_times -= ui_hour * 1080000;
            ui_minute = u32_times / 18000;
            u32_times -= ui_minute * 18000;
            ui_second = u32_times / 300;
            u32_times -= ui_second * 300;
            ui_msecond = u32_times * 1000 / 300;
        }

        /* 日期格式HH:mm:ss.xxx */
        p_time = (char *)frmalloc(12 + 1);
        if (p_time == NULL)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        snprintf(p_time, 13, "%02d:%02d:%02d.%03d"
                 , ui_hour, ui_minute, ui_second, ui_msecond);
    }
    else
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 创建参数节点 */
    i_ret = frtds_create_param(p_time, FRTIME, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_time);
        return APM_L7_ANALYZE_FAIL;
    }
    return APM_L7_ANALYZE_SUCC;
}

int frtds_convert_to_timen(Frbyte_Packet *p_st_data
                          , LITTLE_BIG_ENDIAN i_endian
                          , int i_whole_flg
                          , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_len = 0;

    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 1)
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    bytebuff_get_char(p_st_data, &u8_len);
    /* 解析date */
    if (u8_len)
    {
        i_ret = frtds_convert_to_time(p_st_data, u8_len, i_endian
                                    , i_whole_flg, pp_st_value);
    }
    else
    {
        i_ret = frtds_create_param(NULL, FRTIME, pp_st_value);
    }
    return i_ret;
}

int frtds_convert_to_mssql_timen(Frbyte_Packet *p_st_data
                               , unsigned int ui_scale
                               , LITTLE_BIG_ENDIAN i_endian
                               , int i_whole_flg
                               , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = FR_SUCC;
    uint8_t u8_timen_len = 0;
    uint32_t u32_times = 0;
    unsigned long ul_times = 0;
    unsigned long ul_hour = 0;
    unsigned long ul_minute = 0;
    unsigned long ul_second = 0;
    unsigned int ui_loop = 0;
    unsigned int ui_len = 0;
    char *p_timen = NULL;
    char arr_times[20] = {0};
    char arr_int[20] = {0};
    char arr_buff[20] = {0};
    char *p_tmp = NULL;

    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 1)
    {
        goto unknow;
    }
    /* 取得长度位,并跳过 */
    bytebuff_get_char(p_st_data, &u8_timen_len);

    /* 格式判断 */
    if (bytebuff_remaining(p_st_data) < (int)u8_timen_len)
    {
        goto unknow;
    }

    /*
    * SCALE     1    2    3    4    5    6    7
    * LENGTH  0x03 0x03 0x04 0x04 0x04 0x05 0x05
    */
    if (u8_timen_len == 3)
    {
        /* 格式判断 */
        if (ui_scale != 1 && ui_scale != 2)
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else if (u8_timen_len == 4)
    {
        /* 格式判断 */
        if (ui_scale != 3 && ui_scale != 4)
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else if (u8_timen_len == 5)
    {
        /* 格式判断 */
        if (ui_scale != 5 && ui_scale != 6 && ui_scale != 7)
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else if (u8_timen_len != 0)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 0时数据位NULL */
    if (u8_timen_len != 0)
    {
        i_ret = bytebuff_get_bytes(p_st_data, arr_buff, u8_timen_len);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        /* 取值 */
        if (i_endian == BYTE_LITTLE_ENDIAN)
        {
            while (u8_timen_len--)
            {
                u32_times = (u32_times << 8) | (unsigned char)arr_buff[u8_timen_len];
            }
        }
        else
        {
            while (ui_loop < u8_timen_len)
            {
                u32_times = (u32_times << 8) | (unsigned char)arr_buff[ui_loop++];
            }
        }

        /* 分配足够内存，时间格式为hh:mm:ss.xxxxxxx */
        p_timen = (char *)frmalloc(16 + 1);
        if (p_timen == NULL)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        /* 将u32_times转换成时间格式hh:mm:ss.xxxxxxx */
        snprintf(arr_times, sizeof(arr_times), "%u", u32_times);
        ui_len = strlen(arr_times);
        /* 整数部分+小数部分 */
        if (ui_len > ui_scale)
        {
            strncpy(arr_int, arr_times, sizeof(arr_int));
            arr_int[ui_len - ui_scale] = '\0';
            ul_times = strtoul(arr_int, 0, 0);
            ul_second = ul_times%60;
            ul_times = ul_times/60;
            ul_minute = ul_times%60;
            ul_hour = ul_minute/60;
            p_tmp = arr_times;
            snprintf(p_timen, 17, "%02lu:%02lu:%02lu.%s"
                    , ul_hour, ul_minute, ul_second, p_tmp + ui_len - ui_scale);
        }
        /* 小数部分 */
        else
        {
            /* 初始化 */
            snprintf(p_timen, 17, "00:00:00.0000000");
            /* 设置小数 */
            snprintf(p_timen + 9 + ui_scale - ui_len, 8, "%s", arr_times);
        }
    }

    /* 创建参数节点 */
    i_ret = frtds_create_param(p_timen, FRTIME, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_timen);
        return APM_L7_ANALYZE_FAIL;
    }
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == FR_YES)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

int frtds_get_datetimes(Frbyte_Packet *p_st_data
                       , int ui_scale
                       , int ui_zone_len
                       , LITTLE_BIG_ENDIAN i_endian
                       , int i_whole_flg
                       , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = FR_SUCC;
    uint8_t u8_datetimes_len = 0;
    /* date */
    int i_days = 0;
    unsigned int ui_year = 0;
    unsigned int ui_month = 0;
    unsigned int ui_day = 0;
    unsigned int ui_loop = 0;
    unsigned int ui_len = 0;
    /* times */
    uint32_t u32_times = 0;
    unsigned long ul_times = 0;
    unsigned long ul_hour = 0;
    unsigned long ul_minute = 0;
    unsigned long ul_second = 0;
    /* zone */
    uint16_t u16_zone_value = 0;
    short s_zone_value = 0;
    int i_zone_value = 0;
    char c_zone_wps = '+';
    int i_zone = 0;
    int i_mzone = 0;
    unsigned int ui_date_len = 3;
    unsigned int u8_timen_len = 0;
    char *p_datetimes = NULL;
    char *p_datetimes_tmp = NULL;
    char arr_days[4] ={0};
    char arr_times[20] = {0};
    char arr_int[20] = {0};
    char arr_buff[3] = {0};
    //Frdata_field *p_st_value = NULL;
    char *p_tmp = NULL;

    /* 格式判断 */
    if (bytebuff_remaining(p_st_data) < 1)
    {
        goto unknow;
    }

    /* 取得长度位,并跳过 */
    bytebuff_get_char(p_st_data, &u8_datetimes_len);

    /* 格式判断 */
    if (bytebuff_remaining(p_st_data) < u8_datetimes_len)
    {
        goto unknow;
    }
    /* 取得除去时间长度的DateTime */
    u8_datetimes_len -= ui_zone_len;

    /*
    * SCALE     1    2    3    4    5    6    7
    * LENGTH  0x06 0x06 0x07 0x07 0x08 0x08 0x08
    */
    if (u8_datetimes_len == 6)
    {
        /* 格式判断 */
        if (ui_scale != 1 && ui_scale != 2)
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else if (u8_datetimes_len == 7)
    {
        /* 格式判断 */
        if (ui_scale != 3 && ui_scale != 4)
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else if (u8_datetimes_len == 8)
    {
        /* 格式判断 */
        if (ui_scale != 5 && ui_scale != 6 && ui_scale != 7)
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else if (u8_datetimes_len == 0)
    {
        i_ret = frtds_create_param(NULL, FRTIME, pp_st_value);
        return i_ret;
    }
    else
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 取得天数信息 */
    i_ret = bytebuff_get_bytes(p_st_data, arr_days, 3);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    if (i_endian == BYTE_LITTLE_ENDIAN)
    {
        while (ui_date_len--)
        {
            i_days = (i_days << 8) | (unsigned char)arr_buff[ui_date_len];
        }
    }
    else
    {
        while (ui_loop < ui_date_len)
        {
            i_days = (i_days << 8) | (unsigned char)arr_buff[ui_loop++];
        }
    }
    /* 将天数转换为年月日 */
    __frtds_days_fromat(i_days, &ui_year, &ui_month, &ui_day);

    /* 取得秒数信息 */
    i_ret = bytebuff_get_bytes(p_st_data, arr_times, u8_datetimes_len - 3);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 取值 */
    u8_timen_len = u8_datetimes_len - 3;
    if (i_endian == BYTE_LITTLE_ENDIAN)
    {
        while (u8_timen_len--)
        {
            u32_times = (u32_times << 8) | (unsigned char)arr_times[u8_timen_len];
        }
    }
    else
    {
        while (ui_loop < ui_date_len)
        {
            u32_times = (u32_times << 8) | (unsigned char)arr_times[ui_loop++];
        }
    }

    /* 分配足够内存,时间格式YYYY-MM-DD.hh:mm:ss.xxxxxxx +XX:XX(例2014-11-04 12:12:00.0000000 +08:00) */
    p_datetimes = (char *)frmalloc(35 + 1);
    if (p_datetimes == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    p_datetimes_tmp = p_datetimes;
    /* 设置年月日 */
    snprintf(p_datetimes_tmp, 36, "%04d-%02d-%02dT", ui_year, ui_month, ui_day);
    p_datetimes_tmp += 10;

    /* 将u32_times转换成时间格式hh:mm:ss.xxxxxxx */
    snprintf(arr_times, sizeof(arr_times), "%u", u32_times);
    ui_len = strlen(arr_times);
    /* 整数部分+小数部分 */
    if (ui_len > (unsigned int)ui_scale)
    {
        strncpy(arr_int, arr_times, sizeof(arr_int));
        arr_int[ui_len - ui_scale] = '\0';
        ul_times = strtoul(arr_int, 0, 0);
        ul_second = ul_times%60;
        ul_times = ul_times/60;
        ul_minute = ul_times%60;
        ul_hour = ul_minute/60;
        p_tmp = arr_times;
        snprintf(p_datetimes_tmp, 26, "%02lu:%02lu:%02lu.%sZ"
                , ul_hour, ul_minute, ul_second, p_tmp + ui_len - ui_scale);
    }
    /* 小数部分 */
    else
    {
        /* 初始化 */
        snprintf(p_datetimes_tmp, 26, "00:00:00.0000000Z");
        /* 设置小数 */
        snprintf(p_datetimes_tmp + 9 + ui_scale - ui_len, 16, "%s", arr_times);
    }
    p_datetimes_tmp += strlen(p_datetimes_tmp);

    /* 最后根据是否有zone取得zone */
    if (ui_zone_len)
    {
        /* 有时区是不需要Z结尾 */
        p_datetimes_tmp--;
        i_ret = bytebuff_get_short(p_st_data, 2, &u16_zone_value, i_endian);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        s_zone_value = (short)u16_zone_value;
        i_zone_value = s_zone_value;
        if (i_zone_value < 0)
        {
            c_zone_wps = '-';
            i_zone_value = abs(i_zone_value);
        }
        i_zone = i_zone_value/60;
        i_mzone = i_zone_value%60;
        snprintf(p_datetimes_tmp, 35, "%c%02d:%02d", c_zone_wps, i_zone, i_mzone);
    }

    /* 创建参数节点 */
    i_ret = frtds_create_param(p_datetimes, FRTIME, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_datetimes);
        return APM_L7_ANALYZE_FAIL;
    }
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == FR_YES)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

int frtds_convert_to_float(Frbyte_Packet *p_st_data
                         , unsigned int ui_float_len
                         , Frtds_type_float i_float_type
                         , int i_whole_flg
                         , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = FR_SUCC;
    //unsigned int ui_binary_len = 0;
    char arr_buff[8 + 1] = {0};
    //char arr_binary[8 * 16 + 1] = {0};
    char *p_float = NULL;

    /* 数据长度不足 */
    if (ui_float_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    if (ui_float_len == 4)
    {
        i_ret = bytebuff_get_bytes(p_st_data, arr_buff, 4);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        /* binary转float */
        i_ret = __frtds_binary_to_float(arr_buff, i_float_type, &p_float);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        /* 创建参数节点 */
        i_ret = frtds_create_param(p_float, FRFLOAT, pp_st_value);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frfree(p_float);
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else if (ui_float_len == 8)
    {
        i_ret = bytebuff_get_bytes(p_st_data, arr_buff, 8);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        /* binary转double */
        i_ret = __frtds_binary_to_double(arr_buff, i_float_type, &p_float);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        /* 创建参数节点 */
        i_ret = frtds_create_param(p_float, FRDOUBLE, pp_st_value);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frfree(p_float);
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else
    {
        return APM_L7_ANALYZE_FAIL;
    }

    return APM_L7_ANALYZE_SUCC;
}

int frtds_convert_to_floatn(Frbyte_Packet *p_st_data
                          , Frtds_type_float i_float_type
                          , int i_whole_flg
                          , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_len = 0;

    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 1)
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    bytebuff_get_char(p_st_data, &u8_len);
    /* 解析date */
    if (u8_len)
    {
        i_ret = frtds_convert_to_float(p_st_data, u8_len, i_float_type
                                     , i_whole_flg, pp_st_value);
    }
    else
    {
        i_ret = frtds_create_param(NULL, FRFLOAT, pp_st_value);
    }
    return i_ret;
}

int frtds_convert_to_varchar(Frbyte_Packet *p_st_data
                            , int i_whole_flg
                            , LITTLE_BIG_ENDIAN i_endian
                            , unsigned int ui_len_bytes
                            , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = FR_SUCC;
    uint8_t u8_bytes_len = 0;
    uint16_t u16_bytes_len = 0;
    uint32_t u32_bytes_len = 0;
    unsigned int ui_bytes_len = 0;
    char *p_output = NULL;

    /* 基本格式check */
    if (ui_len_bytes > (unsigned int)bytebuff_remaining(p_st_data))
    {
         goto unknow;
    }

    switch (ui_len_bytes)
    {
        case 1:
            /* 取得长度位,并跳过 */
            bytebuff_get_char(p_st_data, &u8_bytes_len);
            ui_bytes_len = u8_bytes_len;
            break;

        case 2:
            i_ret = bytebuff_get_short(p_st_data, 2, &u16_bytes_len, i_endian);
            if (i_ret != FR_SUCC)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            ui_bytes_len = u16_bytes_len;
            break;

        case 4:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_bytes_len, i_endian);
            if (i_ret != FR_SUCC)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            ui_bytes_len = u32_bytes_len;
            break;

        default:
            return APM_L7_ANALYZE_FAIL;
    }

    /* 基本格式check */
    if (ui_bytes_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
         goto unknow;
    }

    /* 取得varchar */
    if (ui_bytes_len)
    {
        p_output = (char *) frmalloc(ui_bytes_len + 1);
        if (p_output == NULL)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        i_ret = bytebuff_get_bytes(p_st_data, p_output, ui_bytes_len);
        if (i_ret != FR_SUCC)
        {
            frfree(p_output);
            return APM_L7_ANALYZE_FAIL;
        }
        p_output[ui_bytes_len] = '\0';
        i_ret = frtds_create_param(p_output, FRSTRING, pp_st_value);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frfree(p_output);
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else
    {
        i_ret = frtds_create_param(NULL, FRSTRING, pp_st_value);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == FR_YES)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

int frtds_convert_to_money(Frbyte_Packet *p_st_data
                          , int i_whole_flg
                          , LITTLE_BIG_ENDIAN i_endian
                          , unsigned int ui_money_len
                          , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = 0;
    uint32_t u32_money_value = 0;
    long long ll_money_value = 0;
    char *p_money = NULL;
    char arr_buffer[8] = {0};

    /* 数据长度不足 */
    if (ui_money_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    /* 根据Money所占据的长度来解析数据
    * For MONEYNTYPE, the only valid lengths are 0x04 and 0x08,
    * which map to smallmoney and money SQL data types respectively
    */
    switch (ui_money_len)
    {
        /* The TDS value is the smallmoney value multiplied by 10000 */
        case 4:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_money_value, i_endian);
            if (i_ret != FR_SUCC)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            /* int型数据的范围是-2147483648 ~ +2147483647，所以此处对应的浮点型为-214748.3648 ~ +214748.3647 */
            p_money = (char *)frmalloc(12 + 1);
            if (p_money == NULL)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            snprintf(p_money, 13, "%d.%04d",u32_money_value/10000, u32_money_value%10000);
            break;

        /* The TDS value is the smallmoney value multiplied by 10000 */
        case 8:
            i_ret = bytebuff_get_bytes(p_st_data, arr_buffer, 8);
            if (i_ret != FR_SUCC)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            ll_money_value = ((unsigned long long )(arr_buffer[0]) << 32)
                           + ((unsigned long long )(arr_buffer[1]) << 40)
                           + ((unsigned long long )(arr_buffer[2]) << 48)
                           + ((unsigned long long )(arr_buffer[3]) << 56)
                           + ((unsigned long long )(arr_buffer[4]))
                           + ((unsigned long long )(arr_buffer[5]) << 8)
                           + ((unsigned long long )(arr_buffer[6]) << 16)
                           + ((unsigned long long )(arr_buffer[7]) << 24);
            /*
            * long long型数据的范围是-9223372036854775808 ~ +9223372036854775807 ，
            * 所以此处对应的浮点型为-922337203685477.5808 ~ +922337203685477.5807
            */
            p_money = (char *)frmalloc(21 + 1);
            if (p_money == NULL)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            snprintf(p_money, 22, "%lld.%04lld",ll_money_value/10000, ll_money_value%10000);
            break;

        default:
            return APM_L7_ANALYZE_FAIL;
    }

    /* 创建参数 */
    i_ret = frtds_create_param(p_money, FRFLOAT, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_money);
        return APM_L7_ANALYZE_FAIL;
    }
    return APM_L7_ANALYZE_SUCC;
}

int frtds_convert_to_moneyn(Frbyte_Packet *p_st_data
                          , int i_whole_flg
                          , LITTLE_BIG_ENDIAN i_endian
                          , Frdata_field **pp_st_value)
{
    if (p_st_data == NULL || pp_st_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_len = 0;

    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 1)
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    bytebuff_get_char(p_st_data, &u8_len);
    /* 解析date */
    if (u8_len)
    {
        i_ret = frtds_convert_to_money(p_st_data, i_whole_flg, i_endian
                                     , u8_len, pp_st_value);
    }
    else
    {
        i_ret = frtds_create_param(NULL, FRFLOAT, pp_st_value);
    }
    return i_ret;
}

int frtds_skip_fixed_len(Frbyte_Packet *p_st_data
                         , int i_whole_flg
                         , unsigned int ui_len)
{
    if (p_st_data == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = 0;

    /* 数据长度不足 */
    if (ui_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    /* skip length */
    i_ret = bytebuff_skip(p_st_data, ui_len);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    return APM_L7_ANALYZE_SUCC;
}

int frtds_skip_var_len(Frbyte_Packet *p_st_data
                       , int i_whole_flg
                       , LITTLE_BIG_ENDIAN i_endian
                       , unsigned int ui_var_len)
{
    if (p_st_data == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    int i_ret = 0;
    uint8_t u8_len = 0;
    uint16_t u16_len = 0;
    uint32_t u32_len = 0;
    unsigned int ui_len = 0;

    /* 数据长度不足 */
    if (ui_var_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    switch (ui_var_len)
    {
        case 1:
            i_ret = bytebuff_get_char(p_st_data, &u8_len);
            ui_len = u8_len;
            break;

        case 2:
            i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, i_endian);
            ui_len = u16_len;
            break;

        case 4:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, i_endian);
            ui_len = u32_len;
            break;

        default:
            return APM_L7_ANALYZE_FAIL;

    }

    /* 数据长度不足 */
    if (ui_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        /* 还有本次请求未接收完了的数据 */
        if (i_whole_flg == FR_NO)
        {
            bytebuff_set_skip(p_st_data, ui_len - bytebuff_remaining(p_st_data));
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    /* skip length */
    i_ret = bytebuff_skip(p_st_data, ui_len);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    return APM_L7_ANALYZE_SUCC;
}

int frtds_detect_sybase(Frbyte_Packet *p_st_data
                       , int i_whole_flg
                       , int i_packet_type
                       , int *p_i_req_resp)
{
    if (p_st_data == NULL)
    {
        return FRTDS_SYBASE_UNKNOW;
    }

    int i_ret = FR_SUCC;
    uint32_t u32_login7_len = 0;
    unsigned int ui_remaining_len = 0;
    char arr_ver[4] = {0};

    /* 根据packet type进行初步判定 */
    switch (i_packet_type)
    {
        case 3:
            *p_i_req_resp = FRTDS_DIRECT_REQUEST;
            return FRTDS_SYBASE_NO;

        /* 以下为sybase和mssql都有的 */
        case 1:
        //case 3:  sybase 暂时不支持
        case 6:
        case 7:
            *p_i_req_resp = FRTDS_DIRECT_REQUEST;
            return FRTDS_SYBASE_UNKNOW;

        case 14:
            *p_i_req_resp = FRTDS_DIRECT_UNKNOWN;
            return FRTDS_SYBASE_UNKNOW;

        case 17: //sybase不支持
        case 18: //sybase不支持
            return FRTDS_SYBASE_NO;

        case 4:  //sqlserver和sybase的响应结果可能完全相同
            *p_i_req_resp = FRTDS_DIRECT_RESPONSE;
            return FRTDS_SYBASE_UNKNOW;

        case 10: //sqlserver不支持
        case 11: //sqlserver不支持
            *p_i_req_resp = FRTDS_DIRECT_RESPONSE;
            return FRTDS_SYBASE_YES;

        case 5:  //sqlserver不支持
            *p_i_req_resp = FRTDS_DIRECT_UNKNOWN;
            return FRTDS_SYBASE_YES;

        case 2:  //sqlserver tds4.2的login，不支持。仅当做tds5.0login
        case 8:  //sqlserver不支持
        case 9:  //sqlserver不支持
        case 12: //sqlserver不支持
        case 13: //sqlserver不支持
        case 24: //sqlserver不支持
        case 25: //sqlserver不支持
        case 26: //sqlserver不支持
        case 27: //sqlserver不支持
        case 28: //sqlserver不支持
            *p_i_req_resp = FRTDS_DIRECT_REQUEST;
            return FRTDS_SYBASE_YES;

        case 15: //sqlserver不支持
            *p_i_req_resp = FRTDS_DIRECT_UNKNOWN;
            return FRTDS_SYBASE_YES;
            break;

        /* 由于有可能是mssql的login信息,必须做特殊处理 */
        case 16:
            *p_i_req_resp = FRTDS_DIRECT_REQUEST;
            break;

        default:
            frdbg("never.happen!\n");
            *p_i_req_resp = FRTDS_DIRECT_UNKNOWN;
            return FRTDS_SYBASE_UNKNOW;
    }

    /* 判断是不是mssql的login7
    *  依据1：LOGIN7数据长度位四位的unsigned int小字节值序
    *  依据2：LOGIN7 stream MUST NOT be longer than 128K-1(byte) bytes.
    */
    ui_remaining_len = bytebuff_remaining(p_st_data);
    if (ui_remaining_len < 4)
    {
        return FRTDS_SYBASE_NO;
    }
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_login7_len, BYTE_LITTLE_ENDIAN);
    if (i_ret != FR_SUCC)
    {
        return FRTDS_SYBASE_UNKNOW;
    }
    /* 符合LOGIN7的长度条件 */
    if (u32_login7_len < 131071 && ui_remaining_len >= u32_login7_len)
    {
        /* 为了进一步判定正确定性，再取得version做判断 */
        if (u32_login7_len < 8)
        {
            return FRTDS_SYBASE_YES;
        }
        i_ret = bytebuff_get_bytes(p_st_data, arr_ver, 4);
        if (i_ret != FR_SUCC)
        {
            return FRTDS_SYBASE_UNKNOW;
        }
        /* TDS Version */
        if (memcmp(arr_ver, "\x00\x00\x00\x70", 4) == 0
           || memcmp(arr_ver, "\x00\x00\x00\x71", 4) == 0
           || memcmp(arr_ver, "\x01\x00\x00\x71", 4) == 0
           || memcmp(arr_ver, "\x02\x00\x09\x72", 4) == 0
           || memcmp(arr_ver, "\x03\x00\x0A\x73", 4) == 0
           || memcmp(arr_ver, "\x03\x00\x0B\x73", 4) == 0
           || memcmp(arr_ver, "\x04\x00\x00\x74", 4) == 0)
        {
            return FRTDS_SYBASE_NO;
        }
        else
        {
            return FRTDS_SYBASE_YES;
        }
    }
    else
    {
        return FRTDS_SYBASE_YES;
    }
}

